Static speculation techniques have been used to allow a compiler, or an application, to schedule a load (speculative load) before it is known that the reference is needed. For example, the speculative load may be scheduled when the compiler, that is associated with hardware, has good information to suggest that the load value is likely to be used, but the compiler does not have the necessary information to indicate the load value would necessarily be used. In these schemes, the hardware does not raise any exceptions visible to the instruction stream containing the speculative load.
When it is determined that the results of the speculative load are needed, the compiler can check the exception indicator to see if the speculative load caused an exception. In the case where an exception is generated, the compiler can invoke some mechanism to re-execute the load instruction, and potentially re-execute any other instructions that were speculatively computed based on the value speculatively loaded.
As such, speculative loads enable compilers to generate references to unqualified addresses. The load addresses are protected by the virtual memory system, that is, only memory for current processes are readable. More particularly, virtual translations to memory mapped Input/Output (I/O) locations are marked with a unique memory attribute in a Translation Lookaside Buffer (TLB). This attribute indicates that the memory location is “unsafe” for speculation. As such, the attribute indicates that there may be side-effects to reading from or writing to these locations. In other instances, the attribute indicates that addresses in a virtual memory mapped I/O page may not respond to reads or writes.
Because of the “unsafe” nature of referencing memory mapped I/O addresses in a speculative manner, a speculative load is defined to abort a load to an address with an I/O TLB attribute and set the deferred exception indicator. For physical speculative loads (loads when data translation is disabled) there is no TLB to query for a memory attribute. In that case, the processor behaves as if the target of a physical speculative load is “unsafe”, aborts the load and sets the deferred exception indicator.
Software execution at the interrupt handler has an increasing role in emulating or monitoring instruction execution. Instruction emulation may occur for a number of reasons, ranging from executing new instructions on an old version of a processor, to virtualizing a processor and emulating privileged instructions, etc. Instruction monitoring may be done to assist in debugging an operation environment or for performance characterization.
Previously, speculative loads were not used in the context of qualified addresses. For example, the memory address referenced by an interruption handler is known to be a valid virtual memory address, such as, when the interruption handler is storing information into a known virtual address. As such, the virtual memory address is not unqualified. In some first-level interruption handlers, speculative loads would defer all exceptions without causing an interruption. References to virtual memory by the interruption handler are deferred until it is known that all the expected conditions of virtual memory exist, such as, when data translation is enabled. Such is the case, for example, when performing performance profiling and characterization of an application.
Memory translation settings in some low level interruption handlers are unchanged from the interrupted context. For example, if data translation is enabled in the interrupted context, it will be enabled in the interruption handling context as well. Low-level interruption handlers for emulation or monitoring functions can be invoked when data translation is enabled or disabled.
However, if data translation is disabled, the interruption handler could access physical memory addresses that could cause an application to abort or the system to fail. For example, accessing Input/Output (I/O) locations may cause side-effects from reading from or writing to these locations. These side-effects could be so severe as to cause system failure.
Prior Art FIG. 1 is a flow chart 100 illustrating steps in a method for accessing memory addresses when the conditions of virtual memory are unknown, such as whether data translation is enabled. The process in flow chart 100 defers execution until the status of virtual memory is determined.
In flow diagram 100, an interrupt is received, for example, by a low-level interruption handler, and load instructions are processed for execution. In step 110, the interruption handler checks the status of virtual memory 110. This is necessary to ensure that the addresses referenced by the load instructions are translated into virtual addresses.
In step 120, the interruption handler determines if the data translation for translating the virtual memory is enabled. If data translation is enabled, then the interruption handler can correctly access the virtual memory addresses, and the compiler continues the mainline code to begin executing the critical task as defined by the load instructions, in step 140.
On the other hand, if data translation of the virtual memory is not enabled, then the interruption handler sets the expected preconditions in virtual memory, for example, enabling data translation, in step 130. Thereafter, the interruption handler returns to the mainline code to begin executing the critical task as defined by the load instructions, in step 140. In step 150, the return results from the executed load operation are committed (e.g., written to memory).
Because of the relatively large time expense of checking the status of the virtual memory, an unfortunate performance penalty is realized by checking and enabling data translation before performing the real task of the interruption handler. This performance sacrifice is especially pronounced when ensuring and enabling data translation upon entry of an interruption handler in the areas of software instruction emulation or the monitoring of instruction execution.